/**
 * 
 */
package it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.ActionCoordinateInfo;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.ActionMediator;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.AddCharacterInfo;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.EndTurnAction;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.actions.StartingPointAction;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.stats.StatsFactory;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.BattlePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.player.SimplePlayer;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.Chessboard;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.Map;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.world.SpawnCoordinate;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.events.EventManager;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.netgame.BoomerangProtocol;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.netgame.OnLineEnemyController;
import it.unical.canonaco.rende.igpe.game.cbv.logiclayer.engine.component.pawn.Character;

/**
 * @author Massimo Canonaco
 *
 */
public class MatchOnLineManager extends MatchManager 
{
	/** */
	private int startingPlayerIndex;
	
	/** */
	private OnLineEnemyController enemyController;
	
	/** */
	public MatchOnLineManager(int startingSkillPoints, int skillPoints,	int max, StatsFactory factory, OnLineEnemyController automaticEnemy) 
	{
		super(startingSkillPoints, skillPoints, max, factory);
		enemyController = automaticEnemy;
	}

	/** */
	public MatchOnLineManager(MatchManager matchManager, OnLineEnemyController automaticEnemy)
	{
		super(matchManager);
		enemyController = automaticEnemy;
	}
	
//	/**It's really similar to the parent's update method, but there're some checks on the automated player condition; so we can synchronize the two clients. */
//	@Override
//	public void update()
//	{
//		if(!isOverTimeTurn())
//		{
//			skipTime();
//		}
//		
////		if(noTimeLeft())
////		{
//			boolean enemyOn = getCurrentPlayer() == getEnemy(),
//					currentOff = getClientPlayer().getActions().getCurrentAction().isFinished();
//
//			// If there's no time.
//			if(noTimeLeft())
//			{
//				// If the current action is finished
//				if(currentOff)
//				{
//					ActionMediator mediator = getCurrentPlayer().getActions();
//					// Check if remote player's turn and check if there're some action to be still made.
//					if(enemyOn && 
//						(!enemyController.getActions().isEmpty() || ( mediator.getCurrentAction().getActionIdentifier() != EndTurnAction.GUID && mediator.isNoAction() )))
//					{
//						// Must set the over time because we need these action to be executed for "synchronizing" the two clients.
//						setOverTimeTurn(true);
//					}
//					else
//					{
//						nextTurn();
//					}
//				}
//				else 
//				{
//					setOverTimeTurn(true);
//				}
//			}
//			
//			playPlayerAction();
//
////		}
//	}
	
//	/** */
//	public void init(SimplePlayer one, SimplePlayer two, BattlePlayer playerOne, BattlePlayer playerTwo, Map arena)
//	{
//		// Setting all the required actions and informations.
//		super.init(one, two, playerOne, playerTwo, arena);
//		
//		placeWarriors(playerOne.getActions(), playerOne.getCharacters(), arena.getArena());
//		placeWarriors(playerTwo.getActions(), playerTwo.getCharacters(), arena.getArena());
//		
//		// Setting the index of the player who's going to play the first turn.
//		startingPlayerIndex = (new Random()).nextInt()%2;
//	}
	
//	/** */
//	public void setUp(BoomerangProtocol protocol)
//	{
//		if(protocol.is)
//		{
//			BattlePlayer playerOne = getClientPlayer(),	playerTwo = getEnemy();
//			Chessboard arena = getMap().getArena();
//			
//			placeWarriors(playerOne.getActions(), playerOne.getCharacters(), arena);
//			placeWarriors(playerTwo.getActions(), playerTwo.getCharacters(), arena);
//			
//			// Setting the index of the player who's going to play the first turn.
//			startingPlayerIndex = (new Random()).nextInt()%2;
//		}
//	}
//	public void 
	/** */
	public void startMatch(final int STARTING_PLAYER)
	{
		super.startMatch(startingPlayerIndex);
	}
	
	/** */
	public void placeWarriors(ActionMediator actionMediator, List<Character> warriors, Chessboard currentBoard)
	{
		
		LinkedList<SpawnCoordinate> spawns = currentBoard.getSpawnCells().getAllElements();
		Random randomGenerator = new Random();
		SpawnCoordinate spawn = null;
		
		int n = spawns.size();
		
		for (Character warrior : warriors) 
		{
			actionMediator.setAction(StartingPointAction.GUID);
			// Searching for a free spawnCell
			do
			{
				// Get a random spawn
				spawn = spawns.get(randomGenerator.nextInt(n));
			}
			// Check if it's free. If it isn't, get another one.
			while(spawn == null || !currentBoard.isFree(spawn.getIRow(), spawn.getIColumn()));
			
			// We have the spawn cell where to place the character.
			// Add the informations for executing the action.
			actionMediator.addActionInfo(new AddCharacterInfo(warrior));
			actionMediator.addActionInfo(new ActionCoordinateInfo(spawn.getIRow(), spawn.getIColumn()));
			
			// Execute the action.
			actionMediator.playAction();
		}
		
	}

	/**
	 * @return the startingPlayerIndex
	 */
	public int getStartingPlayerIndex() {
		return startingPlayerIndex;
	}

	/**
	 * @param startingPlayerIndex the startingPlayerIndex to set
	 */
	public void setStartingPlayerIndex(int startingPlayerIndex) {
		this.startingPlayerIndex = startingPlayerIndex;
	}
	
	
}
